package com.eastfair.projectcore.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.eastfair.auth.api.AuthServiceFeign;
import com.eastfair.auth.dto.OrganizationDTO;
import com.eastfair.auth.dto.OrganizationRoleDto;
import com.eastfair.auth.entity.Organization;
import com.eastfair.auth.enumeration.OrganizationOrgTypeEnum;
import com.eastfair.auth.enumeration.ResourceOrganizationResourceTypeEnum;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.projectcore.dao.ExhibitionMapper;
import com.eastfair.projectcore.dto.ExhibitionDTO;
import com.eastfair.projectcore.entity.Exhibition;
import com.eastfair.projectcore.service.ExhibitionService;
import com.eastfair.boot.service.SuperServiceImpl;
import com.eastfair.core.base.R;
import com.eastfair.projectcore.service.ProjectDbService;
import com.eastfair.projectcore.vo.ExhibitionVO;
import com.eastfair.uid.service.SelfUidService;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import static com.eastfair.core.base.R.SUCCESS_CODE;

/**
 * <p>
 * 业务实现类
 *
 * </p>
 *
 * @author ligang
 * @date 2021-07-22
 */
@Slf4j
@Service
public class ExhibitionServiceImpl extends SuperServiceImpl<ExhibitionMapper, Exhibition> implements ExhibitionService {

    @Autowired
    private ExhibitionMapper exhibitionMapper;
    @Autowired
    AuthServiceFeign authServiceFeign;

    @Autowired
    ProjectDbService projectDbService;

    /**
     * 处理新增相关处理
     *
     * @param model 实体
     * @return 是否成功
     */
    @Override
    protected R<Boolean> handlerSave(Exhibition model) {
        //雪花ID
        model.setId(projectDbService.getSelfUid(model.getProjectId()));
        return R.successDef();
    }


    /**
     * 处理逻辑删除相关处理
     *
     * @param modelList 实体
     * @return 是否成功
     */
    @Override
    protected R<Boolean> handlerRemoveByIdsOfLogic(Collection<Exhibition> modelList) {
        modelList.forEach(s -> s.setIsDeleted(BusinessConstant.YES));
        // TODO: 2021/10/29 这里需要操作其他业务，如清空角色等
        return R.successDef();
    }

    @Override
    @GlobalTransactional(name = "createExhibition", rollbackFor = Exception.class)
    public R<Exhibition> executeCreateExhibition(ExhibitionDTO exhibitionDTO) {
        //展会是否存在
        Exhibition exhibition = exhibitionIsExist(exhibitionDTO);
        if (exhibition == null) {
            exhibition = new Exhibition();
            BeanUtil.copyProperties(exhibitionDTO, exhibition);
            //创建
            exhibition.setProjectId(ContextUtil.getProjectId());
            save(exhibition);
            //同步到组织角色
            OrganizationDTO organizationDTO = new OrganizationDTO();
            organizationDTO.setName(exhibition.getName());
            organizationDTO.setResourceId(exhibition.getId());
            organizationDTO.setOrgType(OrganizationOrgTypeEnum.EXHIBITION);
            organizationDTO.setResourceType(ResourceOrganizationResourceTypeEnum.SPONSOR);
            organizationDTO.setProjectId(exhibition.getProjectId());
            R<Organization> organizationR = authServiceFeign.createExhibition(organizationDTO);
            if (organizationR.getCode() == SUCCESS_CODE) {
                //将角色注入到公司组织
                OrganizationRoleDto orgRoleDto = new OrganizationRoleDto();
                orgRoleDto.setRoleIds(exhibitionDTO.getRoleIds());
                orgRoleDto.setOrganizationId(organizationR.getData().getId());
                orgRoleDto.setConduction(false);
                authServiceFeign.addOrgRole(orgRoleDto);
            }
        }
        return R.success(exhibition);
    }

    public void assemblyUpdEntity(ExhibitionDTO exhibitionDTO, Exhibition exhibition) {
        if (StringUtils.isNotBlank(exhibitionDTO.getEId())) {
            exhibition.setEId(exhibitionDTO.getEId());
        }

        if (StringUtils.isNotBlank(exhibitionDTO.getBId())) {
            exhibition.setBId(exhibitionDTO.getBId());
        }

        if (StringUtils.isNotBlank(exhibitionDTO.getName())) {
            exhibition.setName(exhibitionDTO.getName());
        }

        if (StringUtils.isNotBlank(exhibitionDTO.getEnName())) {
            exhibition.setEnName(exhibitionDTO.getEnName());
        }

        if (StringUtils.isNotBlank(exhibitionDTO.getAddress())) {
            exhibition.setAddress(exhibitionDTO.getAddress());
        }

        if (StringUtils.isNotBlank(exhibitionDTO.getEnAddress())) {
            exhibition.setEnAddress(exhibitionDTO.getEnAddress());
        }

        if (StringUtils.isNotBlank(exhibitionDTO.getLogoImage())) {
            exhibition.setLogoImage(exhibitionDTO.getLogoImage());
        }

        if (StringUtils.isNotBlank(exhibitionDTO.getAdvertsVideo())) {
            exhibition.setAdvertsVideo(exhibitionDTO.getAdvertsVideo());
        }

        if (StringUtils.isNotBlank(exhibitionDTO.getAdvertsImage())) {
            exhibition.setAdvertsImage(exhibitionDTO.getAdvertsImage());
        }

        if (exhibitionDTO.getStartTime() != null) {
            exhibition.setStartTime(exhibitionDTO.getStartTime());
        }

        if (exhibitionDTO.getEndTime() != null) {
            exhibition.setEndTime(exhibitionDTO.getEndTime());
        }

        if (exhibitionDTO.getLiveLengthSingle() != null) {
            exhibition.setLiveLengthSingle(exhibitionDTO.getLiveLengthSingle());
        }

        if (exhibitionDTO.getLiveLengthTotal() != null) {
            exhibition.setLiveLengthTotal(exhibitionDTO.getLiveLengthTotal());
        }

        if (exhibitionDTO.getIsDeleted() != null) {
            exhibition.setIsDeleted(exhibitionDTO.getIsDeleted());
        }

    }

    @Override
    public R<Exhibition> executeUpdExhibition(ExhibitionDTO exhibitionDTO) {
        Exhibition exhibition = getById(exhibitionDTO.getId());
        if (exhibition == null) {
            return R.fail("更新失败");
        }
        assemblyUpdEntity(exhibitionDTO, exhibition);
        //更新
        updateById(exhibition);
        //替换projectId 全局id
        ContextUtil.setProjectId(exhibition.getProjectId());
        //更新组织
        OrganizationDTO organizationDTO = new OrganizationDTO();
        organizationDTO.setName(exhibition.getName());
        organizationDTO.setResourceId(exhibition.getId());
        organizationDTO.setResourceType(ResourceOrganizationResourceTypeEnum.SPONSOR);
        organizationDTO.setProjectId(exhibition.getProjectId());
        R<Organization> organizationR = authServiceFeign.updExhibition(organizationDTO);
        if (organizationR.getCode() == SUCCESS_CODE) {
            Long orgId = organizationR.getData().getId();
            //重新将角色注入到项目组织
            OrganizationRoleDto orgRoleDto = new OrganizationRoleDto();
            orgRoleDto.setRoleIds(exhibitionDTO.getRoleIds());
            orgRoleDto.setOrganizationId(orgId);
            orgRoleDto.setConduction(false);
            authServiceFeign.updOrgRole(orgRoleDto);
        }
        return R.success(exhibition);
    }

    @Override
    public ExhibitionVO getAndRoleById(Long id) {
        Exhibition exhibition = getById(id);
        if (exhibition != null) {
            ExhibitionVO exhibitionVo = doToVo(exhibition);
            //查询角色
            //替换projectId 全局id
            ContextUtil.setProjectId(exhibitionVo.getProjectId());
            R<List<Long>> r = authServiceFeign.queryRoleOfResourceId(exhibitionVo.getId());
            if (r.getCode() == SUCCESS_CODE) {
                List<Long> roleIds = r.getData();
                exhibitionVo.setRoleIds(roleIds);
            }
            return exhibitionVo;
        }
        return null;
    }

    public Exhibition exhibitionIsExist(ExhibitionDTO exhibitionDTO) {
        // TODO: 2021/8/28 查询公司是否重复规则
        Exhibition exhibition = BeanUtil.toBean(exhibitionDTO, Exhibition.class);
        List<Exhibition> exhibitionList = list(exhibition, null);
        if (exhibitionList != null && !exhibitionList.isEmpty()) {
            return exhibitionList.get(0);
        }
        return null;
    }

    public List<Exhibition> list(Exhibition exhibition, List<Long> ids) {
        //查询
        QueryWrapper<Exhibition> queryWrapper = new QueryWrapper<>();
        if (exhibition != null) {
            if (exhibition.getId() != null) {
                queryWrapper.lambda().eq(Exhibition::getId, exhibition.getId());
            }
            if (StringUtils.isNotBlank(exhibition.getName())) {
                queryWrapper.lambda().eq(Exhibition::getName, exhibition.getName());
            }
            if (exhibition.getProjectId() != null) {
                queryWrapper.lambda().eq(Exhibition::getProjectId, exhibition.getProjectId());
            }

        }
//        if (ContextUtil.getProjectId() != null) {
//            queryWrapper.lambda().eq(Company::getProjectId, ContextUtil.getProjectId());
//        }
        if (ids != null && !ids.isEmpty()) {
            queryWrapper.lambda().in(Exhibition::getId, ids);
        }
        queryWrapper.lambda().eq(Exhibition::getIsDeleted, BusinessConstant.DELETE_NO);
        List<Exhibition> exhibitionList = list(queryWrapper);
        return exhibitionList;
    }

    @Override
    public List<ExhibitionVO> queryOfProject(Long projectId) {
        Exhibition exhibition = new Exhibition();
        exhibition.setProjectId(projectId);
        List<Exhibition> exhibitionList = list(exhibition, null);
        return doToVos(exhibitionList);
    }


    public ExhibitionVO doToVo(Exhibition exhibition) {
        ExhibitionVO exhibitionVo = new ExhibitionVO();
        BeanUtils.copyProperties(exhibition, exhibitionVo);
        exhibitionVo.setId(exhibition.getId());
        return exhibitionVo;
    }

    public List<ExhibitionVO> doToVos(List<Exhibition> exhibitionList) {
        if (exhibitionList == null || exhibitionList.isEmpty()) {
            return null;
        }
        List<ExhibitionVO> result = new ArrayList<>();
        for (Exhibition exhibition : exhibitionList) {
            result.add(doToVo(exhibition));
        }
        return result;
    }
}
